<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Leaflet.PolylineDecorator - 允许你沿着折线或坐标路径绘制图案（如破折号、箭头或均匀间隔的标记）</title>

  <link rel="stylesheet" href="./js/leaflet.css" />
  <script src="./js/leaflet.js"></script>
  <script src="./js/leaflet.polylineDecorator.js"></script>

  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
    }

    .map-box {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <div class="map-box" id="leafletMapService"></div>

  <script>
    // 加载天地图矢量图层
    let tdtVecW = L.tileLayer(
      "https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=6a9f4b408cb773ba60fb639f3b713d61"
    );

    // 加载天地图矢量注记图层
    let tdtCvaW = L.tileLayer(
      "https://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=6a9f4b408cb773ba60fb639f3b713d61"
    );

    let maps = L.map('leafletMapService', {
      // center: [27.50409, 111.682279],
      center: [52.0, -11.0],
      zoom: 5,
      minZoom: 3,
      maxZoom: 18,
      zoomControl: true,  // 是否隐藏左上角的缩放
      attributionControl: false, // 是否隐藏右下角的信息显示
      layers: [tdtVecW, tdtCvaW]
    });

    /**
     * Pattern definition
     * 
     * offset：（可选）第一个图案符号与线条起点的偏移量。默认值：0。
     * endOffset：（可选）最后一个图案符号与线条终点的最小偏移量。默认值：0。
     * repeat：（必填）图案符号的重复间隔。定义每个连续符号锚点之间的距离。
     * symbol：（必填）符号工厂类的实例。是如何绘制每一段的定义，比如使用L.Symbol.dash, L.Symbol.arrowHead等
     * 
     * offset、endOffset 和 repeat 可以分别定义为以像素为单位的数字，或以字符串为单位的行长百分比（例如："10%"）。
     */

    // --- Simple arrow ---
    let arrow = L.polyline([[57, -19], [60, -12]], {}).addTo(maps);
    // 箭头
    let arrowHead = L.polylineDecorator(arrow, {
      patterns: [
        {
          offset: '100%',
          repeat: 2,
          symbol: L.Symbol.arrowHead({
            pixelSize: 15,
            polygon: false,
            pathOptions: { stroke: true }
          })
        }
      ]
    }).addTo(maps);


    // --- Polygon, with an inner ring ---
    let polygon = L.polygon([[[54, -6], [55, -7], [56, -2], [55, 1], [53, 0]], [[54, -3], [54, -2], [55, -1], [55, -5]]], { color: "#ff7800", weight: 1 }).addTo(maps);
    let pd = L.polylineDecorator(polygon, {
      patterns: [
        { offset: 0, repeat: 10, symbol: L.Symbol.dash({ pixelSize: 0 }) }
      ]
    }).addTo(maps);

    // --- Multi-pattern without Polyline ---
    var pathPattern = L.polylineDecorator(
      [[49.543519, -12.469833], [49.808981, -12.895285], [50.056511, -13.555761], [50.217431, -14.758789], [50.476537, -15.226512], [50.377111, -15.706069], [50.200275, -16.000263], [49.860606, -15.414253], [49.672607, -15.710152], [49.863344, -16.451037], [49.774564, -16.875042], [49.498612, -17.106036], [49.435619, -17.953064], [49.041792, -19.118781], [48.548541, -20.496888], [47.930749, -22.391501], [47.547723, -23.781959], [47.095761, -24.941630], [46.282478, -25.178463], [45.409508, -25.601434], [44.833574, -25.346101], [44.039720, -24.988345]],
      {
        patterns: [
          { offset: 12, repeat: 25, symbol: L.Symbol.dash({ pixelSize: 10, pathOptions: { color: '#f00', weight: 2 } }) },
          { offset: 0, repeat: 25, symbol: L.Symbol.dash({ pixelSize: 0 }) }
        ]
      }
    ).addTo(maps);

    // --- Markers proportionnaly located ---
    var markerLine = L.polyline([[58.44773, -28.65234], [52.9354, -23.33496], [53.01478, -14.32617], [58.1707, -10.37109], [59.68993, -0.65918]], { color: '#ff0000', weight: 10 }).addTo(maps);
    var markerPatterns = L.polylineDecorator(markerLine, {
      patterns: [
        {
          offset: '5%', repeat: '25%', symbol: L.Symbol.marker({
            rotate: true,
            markerOptions: {
              icon: L.icon({
                // iconUrl: 'icon_plane.png',
                iconUrl: './imgs/icon_plane.png',
                iconAnchor: [16, 16]
              })
            }
          })
        }
      ]
    }).addTo(maps);

    // 绘制带箭头的线条（路径）
    let arrowLine = L.polylineDecorator(markerLine, {
      patterns: [
        {
          offset: 30,   // 箭头起始位置距离线条两端的距离
          repeat: 60,  // 箭头重复的间隔
          symbol: L.Symbol.arrowHead({
            pixelSize: 5,  // 箭头大小
            headAngle: 75,  // 角度
            polygon: false,
            pathOptions: { stroke: true, weight: 4, color: '#fff' }
          })
        }
      ]
    }).addTo(maps);

    // --- Example with a rotated marker ---
    var pathPattern = L.polylineDecorator(
      [[42.9, -15], [44.18, -11.4], [45.77, -8.0], [47.61, -6.4], [49.41, -6.1], [51.01, -7.2]],
      {
        patterns: [
          { offset: 0, repeat: 10, symbol: L.Symbol.dash({ pixelSize: 5, pathOptions: { color: '#000', weight: 1, opacity: 0.2 } }) },
          {
            offset: '16%', repeat: '33%', symbol: L.Symbol.marker(
              {
                rotate: true,
                markerOptions: {
                  icon: L.icon({
                    // iconUrl: 'icon_plane.png',
                    iconUrl: './imgs/icon_plane.png',
                    iconAnchor: [16, 16]
                  }),
                  title: 'plane'
                }
              }
            )
          }
        ]
      }
    ).addTo(maps);

    // --- Example with an array of Polylines ---
    var multiCoords1 = [
      [[47.5468, -0.7910], [48.8068, -0.1318], [49.1242, 1.6699], [49.4966, 3.2958], [51.4266, 2.8564], [51.7542, 2.1093]],
      [[48.0193, -2.8125], [46.3165, -2.8564], [44.9336, -1.0107], [44.5278, 1.5820], [44.8714, 3.7353], [45.8287, 5.1855], [48.1953, 5.1416]],
      [[45.9205, 0.4394], [46.7699, 0.9228], [47.6061, 2.5488], [47.7540, 3.3837]]
    ];
    var plArray = [];
    for (var i = 0; i < multiCoords1.length; i++) {
      plArray.push(L.polyline(multiCoords1[i]).addTo(maps));
    }
    L.polylineDecorator(multiCoords1, {
      patterns: [
        { offset: 25, repeat: 50, symbol: L.Symbol.arrowHead({ pixelSize: 15, pathOptions: { fillOpacity: 1, weight: 0 } }) }
      ]
    }).addTo(maps);
  </script>

</body>

</html>